package com.nettest.service;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.nettest.entity.BaseEntity;
import com.nettest.util.TimeUtil;

/**
 * @author Nick Mao
 * @date 2012-09-11
 * @param <T>
 */
public abstract class BaseServiceForHibernate<T> extends HibernateDaoSupport {
	static Logger logger = Logger.getLogger(BaseServiceForHibernate.class
			.getName());

	// 为父类HibernateDaoSupport注入sessionFactory的�?
	@Resource(name = "sessionFactory")
	public void setSuperSessionFactory(SessionFactory sessionFactory) {
		logger.debug("为父类HibernateDaoSupport注入sessionFactory的["
				+ sessionFactory + "]");
		super.setSessionFactory(sessionFactory);
	}

	private Class<T> entityClass;

	@SuppressWarnings("unchecked")
	public BaseServiceForHibernate() {
		entityClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
		logger.debug("得到entity对象类实例[" + entityClass + "]");
	}

	/**
	 * 根据对象是否存在ID新增或更新记�?
	 * 
	 * @param entity对象
	 */
	@SuppressWarnings("unchecked")
	public T save(T o) {
		logger.debug("保存数据，对象：" + o);
		BaseEntity entity = (BaseEntity)o;
		
		String createdBy = getCurrentUserName();
		if(entity.getId() == null) {
			entity.setCreatedBy(createdBy);
			entity.setCreatedDate(TimeUtil.getCurrentDate());
		} else {
			entity.setUpdatedBy(createdBy);
			entity.setUpdatedDate(TimeUtil.getCurrentDate());
		}
		super.getHibernateTemplate().saveOrUpdate(entity);
		return (T)entity;
	}

	/**
	 * 根据主键删除记录
	 * 
	 * @param 主键
	 */
	public void delete(Serializable id) {
		logger.debug("根据主键删除数据，主键：" + id);
		super.getHibernateTemplate().delete(
				super.getHibernateTemplate().load(entityClass, id));
	}

	/**
	 * 根据条件查询记录
	 * 
	 * @param 存储条件的容�?
	 * @return 数据列表
	 */
	@SuppressWarnings("unchecked")
	public List<T> query(Set<Criterion> criterionSet) {
		logger.debug("根据条件查询数据！条件数: " + criterionSet.size());

		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(entityClass);
		for (Criterion o : criterionSet) {
			detachedCriteria.add(o);
		}
		//super.getHibernateTemplate().setCacheQueries(true);
		//super.getHibernateTemplate().setQueryCacheRegion("com.armitage.common");
		return super.getHibernateTemplate().findByCriteria(detachedCriteria);
	}

	/**
	 * 根据条件查询记录
	 * 
	 * @param 存储条件的容�?
	 * @param 存储排序的容�?
	 * @return 数据列表
	 */
	@SuppressWarnings("unchecked")
	public List<T> query(Set<Criterion> criterionSet, Set<Order> orderSet) {
		logger.debug("根据条件和排序查询数据！条件数：" + criterionSet.size() + "，排序数: "
				+ orderSet.size());

		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(entityClass);
		for (Criterion o : criterionSet) {
			detachedCriteria.add(o);
		}
		for (Order o : orderSet) {
			detachedCriteria.addOrder(o);
		}
		return super.getHibernateTemplate().findByCriteria(detachedCriteria);
	}

	/**
	 * 根据条件分页查询记录
	 * 
	 * @param 存储条件的容�?
	 * @param 数据�?��位置
	 *            （第�?��记录�?�?
	 * @param �?��数据�?
	 * @return 数据列表
	 */
	@SuppressWarnings("unchecked")
	public List<T> query(Set<Criterion> criterionSet, int firstResult,
			int maxResults) {
		logger.debug("根据条件分页查询数据！条件数: " + criterionSet.size() + "，记录开始序号："
				+ firstResult + "，最大记录数: " + maxResults);

		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(entityClass);
		for (Criterion o : criterionSet) {
			detachedCriteria.add(o);
		}
		return super.getHibernateTemplate().findByCriteria(detachedCriteria,
				firstResult, maxResults);
	}

	/**
	 * 根据条件分页查询记录
	 * 
	 * @param 存储条件的容�?
	 * @param 存储排序的容�?
	 * @param 数据�?��位置
	 *            （第�?��记录�?�?
	 * @param �?��数据�?
	 * @return 数据列表
	 */
	@SuppressWarnings("unchecked")
	public List<T> query(Set<Criterion> criterionSet, Set<Order> orderSet,
			int firstResult, int maxResults) {
		logger.debug("根据条件和排序分页查询数据！条件数：" + criterionSet.size() + "，排序数: "
				+ orderSet.size() + "，记录开始序号：" + firstResult + "，最大记录数: "
				+ maxResults);

		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(entityClass);
		for (Criterion o : criterionSet) {
			detachedCriteria.add(o);
		}
		for (Order o : orderSet) {
			detachedCriteria.addOrder(o);
		}
		return super.getHibernateTemplate().findByCriteria(detachedCriteria,
				firstResult, maxResults);
	}

	/**
	 * 根据条件取得记录总数[性能严重问题，需改]
	 * 
	 * @param 存储条件的容�?
	 * @return 记录总数
	 */
	public int totalSize(Set<Criterion> criterionSet) {
		logger.debug("根据条件取记录数！条件数:" + criterionSet.size());

		List<T> list = query(criterionSet);
		return list != null ? list.size() : 0;
	}

	/**
	 * 根据主键取得数据
	 * 
	 * @param 主键
	 * @return entity对象
	 */
	public T get(Serializable id) {
		logger.debug("根据主键获取数据，主键：" + id);

		return (T) super.getHibernateTemplate().get(entityClass, id);
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findBySql(final String sql,Object... params) {
		return super.getHibernateTemplate().find(sql,params);
	}
	protected String getCurrentUserName() {
		return "admin";
	}
}